package android.manager.view;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import android.graphics.drawable.Drawable;
import android.location.Address;
import android.location.Geocoder;
import android.manager.database.Database;
import android.os.Bundle;
import android.view.KeyEvent;
import android.widget.Toast;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;
import com.google.android.maps.MyLocationOverlay;
import com.google.android.maps.OverlayItem;

/**
 * This class represents the google map functionality. 
 * It features a zooming and places markers for all of your task locations
 * Clicking on the marker will give a small text box describing the details
 * hitting s switches from street to satellite.
 * @author Joon Ki Hong, Jonathan Betancourt, Griva Patel, Curtis Luckey. Amit Paduvalli 
 */

public class googleMap extends MapActivity {
	private MapView map = null;
	private MyLocationOverlay me = null;
	private ArrayList<String> Locations;
	GeoPoint p;

	/**
	 * This method uses a saved instance object to create the Activity
	 * and handle widgets. It mainly handles map view functionality and utilizes
	 * overlays to present the markers onto the mapview.
	 * 
	 * @param a saved instance state of an activity
	 */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.google_layout);

		map = (MapView) findViewById(R.id.mapView);

		map.getController().setCenter(getPoint(33.7489, -84.3881));
		map.getController().setZoom(14);
		map.setBuiltInZoomControls(true);

		Drawable marker = getResources().getDrawable(R.drawable.ic_launcher);//The image loaded as the marker

		marker.setBounds(0, 0, marker.getIntrinsicWidth(),
				marker.getIntrinsicHeight());

		map.getOverlays().add(new SitesOverlay(marker));//grabs all the markers and puts them on the map

		me = new MyLocationOverlay(this, map);
		map.getOverlays().add(me);
	}

	/**
	 * This method gets the geopoints of the locations
	 * 
	 * @returns a list of geopoints
	 */
	public ArrayList<GeoPoint> getPoints() {
		ArrayList<GeoPoint> points = new ArrayList<GeoPoint>();
		Database dbUser = new Database(googleMap.this);
		dbUser.open();
		Locations = dbUser.getLocations();
		dbUser.close();
		Geocoder geoCoder = new Geocoder(this, Locale.getDefault());
		for (int i = 0; i < Locations.size(); i++) {
			try {
				List<Address> addresses = geoCoder.getFromLocationName(Locations.get(i), 1);
				if (addresses.size() > 0) {
					p = new GeoPoint(
							(int) (addresses.get(0).getLatitude() * 1E6),
							(int) (addresses.get(0).getLongitude() * 1E6));
				}
				points.add(p);
				addresses = geoCoder.getFromLocationName(Locations.get(i), 1);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return points;
	}

	/**
	 * This method is essential for the Activity to resume after starting up.
	 * 
	 */
	@Override
	public void onResume() {
		super.onResume();

		me.enableCompass();//turns compass on during google map
	}

	/**
	 * This method is essential for the Activity to go into the background
	 * but not be killed.
	 * 
	 */
	@Override
	public void onPause() {
		super.onPause();

		me.disableCompass();
	}

	/**
	 * method that enables route calculations
	 * 
	 * @returns boolean if route is displayed or not.
	 */
	@Override
	protected boolean isRouteDisplayed() {
		return (false);
	}

	/**
	 * handles key presses during map activity
	 * 
	 * @returns returns a boolean that checks for key presses.
	 */
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (keyCode == KeyEvent.KEYCODE_S) {
			map.setSatellite(!map.isSatellite()); // switches from satellite to street and vice verse.
			return (true);
		} else if (keyCode == KeyEvent.KEYCODE_Z) {
			map.displayZoomControls(true);
			return (true);
		}

		return (super.onKeyDown(keyCode, event));
	}

	/**
	 * gets a geopoint and handles proper calculations to convert a point to a point on the map
	 * 
	 * @param lat the latitude of the point
	 * @param lon the longitude of the point
	 */
	private GeoPoint getPoint(double lat, double lon) {
		return (new GeoPoint((int) (lat * 1000000.0), (int) (lon * 1000000.0)));
	}

	/**
	 * private class that handles the overlays on the map. Overlays display markers and 
	 * allow for on-touch actions. This overlay allows items to be presented
	 * on the screen anywhere near a designated locations on the map
	 */
	private class SitesOverlay extends ItemizedOverlay<OverlayItem> {
		private List<OverlayItem> items = new ArrayList<OverlayItem>();
		private ArrayList<String> details;
		private String[] Description;
		ArrayList<GeoPoint> points;

		/**
		 * necessary for drawing a marker on the map
		 * 
		 * @param marker the design you want to use as a marker
		 */
		public SitesOverlay(Drawable marker) {
			super(marker);

			Database dbUser = new Database(googleMap.this); // use database to grab the data for the toast information presentation
			dbUser.open();
			details = dbUser.getDetails();
			Description = dbUser.desclist();
			dbUser.close();

			boundCenterBottom(marker);
			points = getPoints();

			for (int i = 0; i < Description.length; i++) {
				items.add(new OverlayItem(points.get(i), Description[i], details.get(i)));
			}
			populate(); // populates the screen with all the markers
		}

		/**
		 * creates an overlay item.
		 * 
		 * @param i index into the item to create
		 * @return Overlay item in the item
		 */
		@Override
		protected OverlayItem createItem(int i) {
			return (items.get(i));
		}

		/**
		 * this handles on-screen touching on markers
		 * 
		 * @param i the index into the item
		 * @return boolean if the screen was tapped or now.
		 */
		@Override
		protected boolean onTap(int i) {
			Toast.makeText(googleMap.this, items.get(i).getSnippet(),
					Toast.LENGTH_SHORT).show();

			return (true);
		}

		/**
		 * gives the size of the items.
		 * 
		 * @param i the index into the item
		 */
		@Override
		public int size() {
			return (items.size());
		}
	}
}
